package com.xbongbong.outerlink.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.outerlink.AbstractProOuterLinkService;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkAddDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkAddGetDTO;
import com.xbongbong.paas.pojo.dto.OuterLinkBaseDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.vo.AfterSaveVO;
import com.xbongbong.paas.pojo.vo.FormDataAddGetVO;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.service.ProModelService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.workorder.pojo.TimeConsumingOutPojo;
import com.xbongbong.pro.workorder.pojo.vo.WorkOrderDataEsListVO;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.WorkOrderStageEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderEntityExt;
import com.xbongbong.saas.enums.WorkOrderNodeStatusEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.WorkOrderModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.saas.service.WorkOrderFormDataService;
import com.xbongbong.saas.service.WorkOrderTemplateService;
import com.xbongbong.workorder.service.WorkOrderBasicService;
import com.xbongbong.workorder.service.WorkOrderStageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;


/**
 * pro 默认外链接口类
 * <p>没有单独实现的业务类型都走此实现</p>
 * <p>时间有限，部分先糅杂在这里，以后各个业务分开，新业务类型应使用新实现</p>
 *
 * @author zheng.li
 **/
@Slf4j
@Service
public class DefaultProOuterLinkServiceImpl extends AbstractProOuterLinkService {

    @Resource
    private WorkOrderTemplateService workOrderTemplateService;

    @Resource
    private WorkOrderStageService workOrderStageService;


    @Resource
    private DataDictionaryModel dataDictionaryModel;


    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;

    @Resource
    private WorkOrderBasicService workOrderBasicService;

    @Resource
    private WorkOrderModel workOrderModel;


    @Resource
    private SaasSaveHelp saasSaveHelp;

    @Resource
    private ProModelService proModelService;

    @Resource
    private WorkOrderFormDataService workOrderFormDataService;

    @Override
    public PaasFormDataEntityExt getFormData(Long dataId, String corpid, Integer businessType) throws XbbException {
        PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
         if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            // 工单特殊处理
            WorkOrderEntity workOrderEntity = workOrderModel.getByKey(dataId, corpid);
            if (Objects.nonNull(workOrderEntity)) {
                BeanUtil.copyProperties(workOrderEntity, paasFormDataEntityExt);
            }
            JSONObject data = paasFormDataEntityExt.getData();
            data.put(FieldTypeEnum.CLOSETIME.getAlias(),workOrderEntity.getCloseTime());
            data.put(FieldTypeEnum.ENDTIME.getAlias(),workOrderEntity.getEndTime());
            paasFormDataEntityExt.setData(data);
        } else {
             // 父类处理
            paasFormDataEntityExt = super.getFormData(dataId,corpid,businessType);
        }

        return paasFormDataEntityExt;
    }


    @Override
    public Map<String, FieldAttrEntity> getExplainMap(List<FieldAttrEntity> explainList, Integer businessType, String corpid, Long formId) {
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode()) && Objects.equals(fieldAttrEntity.getSaasAttr(), WorkOrderEnum.STAGE.getSaasAttr())) {
                if (!Objects.equals(formId, 0L)) {
                    //工单阶段
                    WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateService.getByFormId(formId, corpid);
                    List<ItemPoJo> itemPoJoList = workOrderStageService.getStageNameItemList(workOrderTemplateEntity.getId(), corpid);
                    fieldAttrEntity.setItems(itemPoJoList);
                }
            }
        }
        explainMap = super.getExplainMap(explainList,businessType,corpid,formId);

        if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode())) {
            //此处因为是显示，所以要展示所有的回款单类型
            List<ItemPoJo> itemList = dataDictionaryModel.getDictionaryList4PaymentSheetType(true);
            //先移除原类型解释，然后设置后塞入新的
            for (FieldAttrEntity next : explainList) {
                String attr = next.getAttr();
                if (Objects.equals(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), attr)) {
                    next.setItems(itemList);
                    explainMap.put(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), next);
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode())) {
            //此处因为是显示，所以要展示所有的付款单类型
            List<ItemPoJo> itemList = dataDictionaryModel.getDictionaryList4PaySheetType(true);
            //先移除原类型解释，然后设置后塞入新的
            for (FieldAttrEntity next : explainList) {
                String attr = next.getAttr();
                if (Objects.equals(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), attr)) {
                    next.setItems(itemList);
                    explainMap.put(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), next);
                }
            }
        }
        return explainMap;
    }

    @NonNull
    @Override
    public List<Integer> businessType() {
        // 0：代表默认外链接口
        return Collections.singletonList(0);
    }

    @Override
    public void formatListCondition(FormDataListDTO formDataListDTO) throws XbbException {
        // 先调用父类方法
        super.formatListCondition(formDataListDTO);

        // 子类实现

        //过滤回款计划中有红冲回款计划的数据，针对回款计划特地写的一个方法
        formDataListDTO.setShouldConditions(this.setPaymentIsRed(formDataListDTO));

        Integer businessType = formDataListDTO.getBusinessType();
        List<ConditionsEntityExt> conditions = formDataListDTO.getConditions();
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        if (xbbRefTypeEnum == XbbRefTypeEnum.CUSTOMER_COMMUNICATE) {
            // 排除项目日志
            conditions.add(new ConditionsEntityExt(FieldTypeEnum.LOG_TYPE.getAlias(), "", FieldTypeEnum.LOG_TYPE.getType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(0)));
        }
        formDataListDTO.setConditions(conditions);
    }

    /**
     * 设置红冲条件
     * @param formDataListDTO 入参
     * @return  List<List<ConditionsEntityExt>>
     */
    private List<List<ConditionsEntityExt>> setPaymentIsRed(FormDataListDTO formDataListDTO){
        List<List<ConditionsEntityExt>> shoudConditions = formDataListDTO.getShouldConditions();
        List<ConditionsEntityExt> conditions = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!Objects.equals(formDataListDTO.getBusinessType(),XbbRefTypeEnum.PAYMENT.getCode())){
            return shoudConditions;
        }
        ConditionsEntityExt conditionEqualOne = new ConditionsEntityExt(PaymentEnum.IS_RED.getAttr(), "", FieldTypeEnum.NUM.getType(), ConditionEnum.NOLIKE.getSymbol(), Arrays.asList(1));
        conditions.add(conditionEqualOne);
        shoudConditions.add(conditions);
        return shoudConditions;
    }


    @Override
    public void handleDataList(FormDataListDTO formDataListDTO, PaasFormDataEsListVO paasFormDataEsListVO,WorkOrderDataEsListVO workOrderDataEsListVO) throws XbbException {

        super.handleDataList(formDataListDTO,paasFormDataEsListVO,workOrderDataEsListVO);
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
            // 工单列表特殊处理
            handleSpecial(formDataListDTO, workOrderDataEsListVO, paasFormDataEsListVO);
        }
    }

    @Override
    public void handleGetData(OuterLinkBaseDTO outerLinkBaseDTO, PaasFormDataEntityExt formData, ParseSingleRowDataVO parseSingleRowDataVO, List<FieldAttrEntity> explains) throws XbbException {

    }


    @Override
    public FormDataAddVO addForWorkOrder(OuterLinkAddDTO outerLinkAddDTO,FormDataAddVO formDataAddVO) throws XbbException {
        //工单逻辑与其他业务逻辑分离，在workOrderFormDataService.add中已加异常后的es删除相关数据操作 TODO 待处理
        try {
            if ( outerLinkAddDTO.getBusinessType() ==  XbbRefTypeEnum.WORK_ORDER.getCode() ) {
                //工单
                formDataAddVO = workOrderFormDataService.addForOutLink(outerLinkAddDTO);
                return formDataAddVO;
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            log.error("workOrderFormData 数据库保存表单数据出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formDataAddVO;
    }

    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        saasSaveHelp.beforeSave(validateDataDTO);
    }

    @Override
    public AfterSaveVO insert(FormDataAddDTO formDataAddDTO, PaasFormDataEntity paasFormDataEntity, PaasFormEntityExt paasFormEntityExt) throws XbbException {
        return proModelService.insert(formDataAddDTO, paasFormDataEntity, paasFormEntityExt);
    }

    @Override
    public FormDataAddGetVO addGetForWorkOrder(OuterLinkAddGetDTO outerLinkAddGetDTO, FormDataAddGetVO vo) throws XbbException {
        //工单
        vo = workOrderFormDataService.addGetForOutLink(outerLinkAddGetDTO);
        return vo;
    }


    private void handleSpecial(FormDataListDTO formDataListDTO, WorkOrderDataEsListVO workOrderDataEsListVO, PaasFormDataEsListVO paasFormDataEsListVO) {
        String corpid = formDataListDTO.getCorpid();
        Set<Long> templateIds = new HashSet<>();
        Set<Long> workOrderIdList = new HashSet<>();
        List<WorkOrderEntityExt> workOrderEntityExts = workOrderDataEsListVO.getPaasFormDataESList();
        for (WorkOrderEntityExt workOrderEntityExt : workOrderEntityExts) {
            Long workOrderId = workOrderEntityExt.getId();
            workOrderIdList.add(workOrderId);
            templateIds.add(workOrderEntityExt.getTemplateId());
        }
        Map<Long, WorkOrderTemplateEntity> templateMap = workOrderTemplateModel.getTemplateMap(templateIds, corpid);

        List<PaasFormDataEntityExt> paasFormDataESList = paasFormDataEsListVO.getPaasFormDataESList();
        Map<Long, PaasFormDataEntityExt> paasFormDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
            paasFormDataMap.put(paasFormDataEntityExt.getId(), paasFormDataEntityExt);
        }

        //用于存储阶段名称
        Map<Long,String> workOrderStageNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<WorkOrderStageEntity> workOrderStageEntityList = workOrderStageService.getStagesByTemplateIdIn(templateIds, corpid, false);
        for (WorkOrderStageEntity entity : workOrderStageEntityList) {
            workOrderStageNameMap.put(entity.getId(), entity.getName());
        }

        for (WorkOrderEntityExt entity : workOrderEntityExts){
            WorkOrderTemplateEntity workOrderTemplateEntity = templateMap.get(entity.getTemplateId());
            if (Objects.isNull(workOrderTemplateEntity)) {
                log.error("工单外链查询获取工单模板出错 dataId = " + entity.getId());
                continue;
            }
            PaasFormDataEntityExt entityExt = paasFormDataMap.get(entity.getId());
            if (Objects.isNull(entityExt)) {
                continue;
            }
            //不限时自由工单
            boolean isLimit = Objects.equals(workOrderTemplateEntity.getIsFree(), 1) && Objects.equals(workOrderTemplateEntity.getExpectedTime(), 0);

            JSONObject orderData = entity.getData();
            JSONObject formData = entityExt.getData();
            //老数据data中没有存阶段状态
            if (orderData.containsKey(WorkOrderEnum.NODE_STATUS.getAttr())){
                formData.put(FieldTypeEnum.WORK_ORDER_NODE_STATUS.getAlias(), WorkOrderNodeStatusEnum.getNameByCode(orderData.getInteger(WorkOrderEnum.NODE_STATUS.getAttr()),""));
            } else {
                formData.put(FieldTypeEnum.WORK_ORDER_NODE_STATUS.getAlias(), "");
            }
            formData.put(FieldTypeEnum.WORK_ORDER_STAGE_NAME.getAlias(),workOrderStageNameMap.getOrDefault(entity.getNowStageId(), ""));
            if (isLimit) {
                //data.put(WorkOrderEnum.TIME_OUT.getAttr(), "");
                TimeConsumingOutPojo timeConsumingOutPojo =  workOrderBasicService.workOrderSpecialConsueTime(entity);
                formData.put(WorkOrderEnum.TIME_OUT.getAttr(), timeConsumingOutPojo.getConsumeTimeStr());
            } else {
                TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderConsueTime(entity);
                formData.put(WorkOrderEnum.TIME_OUT.getAttr(), timeConsumingOutPojo.getConsumeTimeStr());
            }
            if (Objects.equals(formDataListDTO.getPlatform(), PlatFormEnum.WEB.getValue())) {
                formData.put(FieldTypeEnum.CLOSETIME.getAlias(), entity.getCloseTime());
                formData.put(FieldTypeEnum.ENDTIME.getAlias(), entity.getEndTime());
            } else {
                if (Objects.nonNull(entity.getCloseTime()) && entity.getCloseTime() > 0) {
                    formData.put(FieldTypeEnum.CLOSETIME.getAlias(), DateTimeUtil.getStringEpochSecond(entity.getCloseTime(), DateTimeUtil.SDFYMDHM));
                }
                if (Objects.nonNull(entity.getEndTime()) && entity.getEndTime() > 0) {
                    formData.put(FieldTypeEnum.ENDTIME.getAlias(), DateTimeUtil.getStringEpochSecond(entity.getEndTime(), DateTimeUtil.SDFYMDHM));
                }
            }
            formData.put(FieldTypeEnum.WORK_ORDER_STATUS.getAlias(),WorkOrderNodeStatusEnum.getByCode(entity.getStatus()).getName());
        }
    }




}
